package com.example.singing.util;

import com.example.singing.model.Score;
import com.example.singing.model.Team;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.stream.Collectors;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URI;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Base64;

/**
 * 智能分析工具类
 * 提供评分算法分析和AI辅助功能
 */
public class SmartAnalyzer {
    
    /**
     * 智能评分校准算法
     * 考虑评委评分习惯和历史数据进行校准
     */
    public static double[] calibrateScores(double[] rawScores, List<Double> judgeBias) {
        if (rawScores == null || rawScores.length == 0) {
            return new double[0];
        }
        
        double[] calibratedScores = new double[rawScores.length];
        
        // 如果没有评委偏差数据，返回原始分数
        if (judgeBias == null || judgeBias.isEmpty()) {
            System.arraycopy(rawScores, 0, calibratedScores, 0, rawScores.length);
            return calibratedScores;
        }
        
        // 根据评委历史评分习惯进行校准
        for (int i = 0; i < rawScores.length; i++) {
            // 确保索引不越界
            int biasIndex = Math.min(i, judgeBias.size() - 1);
            // 校准分数，考虑评委的打分偏差
            calibratedScores[i] = Math.max(0, Math.min(10, rawScores[i] + judgeBias.get(biasIndex)));
        }
        
        return calibratedScores;
    }
    
    /**
     * 高级评分计算算法
     * 考虑分数分布、离群值和权重因素
     */
    public static double calculateAdvancedScore(List<Double> scores) {
        if (scores == null || scores.isEmpty()) {
            return 0;
        }
        
        // 转换为数组并排序
        double[] scoreArray = scores.stream().mapToDouble(Double::doubleValue).toArray();
        java.util.Arrays.sort(scoreArray);
        
        // 检测并处理离群值
        double[] filteredScores = removeOutliers(scoreArray);
        
        // 计算加权平均分，中间分数权重更高
        double totalWeight = 0;
        double weightedSum = 0;
        
        int n = filteredScores.length;
        for (int i = 0; i < n; i++) {
            // 权重分配 - 中间分数权重更高
            double weight = 1.0 + 0.5 * Math.cos(Math.PI * (i - (n - 1) / 2.0) / (n - 1) * 2);
            weightedSum += filteredScores[i] * weight;
            totalWeight += weight;
        }
        
        return totalWeight > 0 ? weightedSum / totalWeight : 0;
    }
    
    /**
     * 移除离群值
     */
    private static double[] removeOutliers(double[] scores) {
        if (scores.length <= 3) {
            return scores; // 数据量太少，不进行离群值检测
        }
        
        // 计算四分位数
        double q1 = getQuantile(scores, 0.25);
        double q3 = getQuantile(scores, 0.75);
        double iqr = q3 - q1;
        
        // 定义离群值边界
        double lowerBound = q1 - 1.5 * iqr;
        double upperBound = q3 + 1.5 * iqr;
        
        // 过滤离群值
        return java.util.Arrays.stream(scores)
                .filter(score -> score >= lowerBound && score <= upperBound)
                .toArray();
    }
    
    /**
     * 获取分位数
     */
    private static double getQuantile(double[] sortedArray, double quantile) {
        int n = sortedArray.length;
        double position = quantile * (n - 1);
        int lowerIndex = (int) Math.floor(position);
        int upperIndex = (int) Math.ceil(position);
        
        if (lowerIndex == upperIndex) {
            return sortedArray[lowerIndex];
        }
        
        double lowerValue = sortedArray[lowerIndex];
        double upperValue = sortedArray[upperIndex];
        double weight = position - lowerIndex;
        
        return lowerValue * (1 - weight) + upperValue * weight;
    }
    
    /**
     * 生成比赛分析报告
     */
    public static String generateCompetitionReport(List<Score> competitionScores, List<Team> teams) {
        StringBuilder report = new StringBuilder();
        report.append("=== 比赛分析报告 ===\n\n");
        
        // 计算平均分分布
        double totalAverage = competitionScores.stream()
                .mapToDouble(Score::getFinalScore)
                .average()
                .orElse(0);
        
        report.append("比赛平均得分: ").append(String.format("%.2f", totalAverage)).append("\n");
        
        // 统计各分数段分布
        Map<String, Long> scoreDistribution = competitionScores.stream()
                .mapToDouble(Score::getFinalScore)
                .boxed()
                .collect(Collectors.groupingBy(score -> {
                    if (score >= 9.0) return "9.0-10.0分";
                    if (score >= 8.0) return "8.0-8.9分";
                    if (score >= 7.0) return "7.0-7.9分";
                    return "7.0分以下";
                }, Collectors.counting()));
        
        report.append("\n分数段分布:\n");
        scoreDistribution.forEach((range, count) -> {
            report.append(range).append(": ").append(count).append("个团队\n");
        });
        
        // 生成AI建议
        report.append("\n=== AI智能建议 ===\n");
        
        if (totalAverage < 7.5) {
            report.append("1. 整体评分偏低，建议适当调整评分标准或提供更多培训资源提升参赛者水平。\n");
        } else if (totalAverage > 9.0) {
            report.append("1. 整体评分偏高，建议严格评分标准以更好地区分参赛队伍水平。\n");
        } else {
            report.append("1. 整体评分分布合理，各团队水平较为均衡。\n");
        }
        
        // 检查评分一致性
        double scoreVariance = competitionScores.stream()
                .mapToDouble(Score::getFinalScore)
                .map(score -> Math.pow(score - totalAverage, 2))
                .average()
                .orElse(0);
        
        if (scoreVariance > 1.0) {
            report.append("2. 各队伍得分差异较大，建议分析高分团队的成功经验并推广。\n");
        }
        
        report.append("3. 建议对评委进行统一培训，减少主观评分差异。\n");
        report.append("4. 可考虑引入更多客观评分指标，如音准、节奏、舞台表现等分项评分。");
        
        return report.toString();
    }
    
    /**
     * AI问答功能 - 优先调用Qwen-Plus API，失败则回退到本地FAQ
     */
    public static String answerQuestion(String question) {
        question = question.toLowerCase().trim();
        
        // 优先尝试调用Qwen-Plus API
        try {
            String apiAnswer = callQwenPlusApi(question);
            if (apiAnswer != null && !apiAnswer.isEmpty()) {
                return "AI解答: " + apiAnswer;
            }
        } catch (Exception e) {

        }
        
        return getLocalAnswer(question);
    }
    
    /**
     * 获取本地知识库的回答
     */
    private static String getLocalAnswer(String question) {
        // 预处理常见问题和回答
        Map<String, String> faq = new HashMap<>();
        
        // 评分相关问题
        faq.put("如何提高评分准确性", 
                "提高评分准确性的方法有：\n" +
                "1. 使用本系统的智能评分校准算法，自动校准评委评分偏差\n" +
                "2. 对评委进行统一培训，明确评分标准和细则\n" +
                "3. 采用多维度评分（音准、节奏、表现力等）\n" +
                "4. 使用高级评分计算算法，自动过滤离群值\n" +
                "5. 建立评分反馈机制，持续优化评分过程");

        faq.put("如何分析比赛结果", 
                "分析比赛结果可以从以下几个方面入手：\n" +
                "1. 查看分数段分布，了解整体水平和竞争激烈程度\n" +
                "2. 比较不同评委的评分差异，识别潜在问题\n" +
                "3. 分析高分团队的特点和优势，提炼成功经验\n" +
                "4. 使用系统生成的比赛分析报告获取AI建议\n" +
                "5. 关注分数分布的正态性，评估评分的合理性");

        faq.put("评分标准", 
                "歌唱比赛常见评分标准包括：\n" +
                "1. 音准与节奏（30%）：准确把握音高和节拍\n" +
                "2. 音色与技巧（25%）：声音质量、音域控制、演唱技巧\n" +
                "3. 情感表达（20%）：歌曲情感的传递和表达能力\n" +
                "4. 舞台表现（15%）：台风、肢体语言、舞台感染力\n" +
                "5. 选曲与创新（10%）：曲目选择的适合性和表现形式的创新性\n" +
                "系统支持自定义评分维度和权重，可根据比赛特点进行调整");

        faq.put("如何减少评委差异", 
                "减少评委评分差异的方法：\n" +
                "1. 统一培训，明确各项评分标准和示例\n" +
                "2. 使用本系统的智能校准算法，自动校准评委的评分习惯\n" +
                "3. 引入参考样例，让评委对评分尺度达成共识\n" +
                "4. 采用去掉最高分和最低分的计算方式\n" +
                "5. 建立评委评价机制，持续提升评委专业性");

        // 比赛管理相关问题
        faq.put("如何组织一场成功的歌唱比赛", 
                "组织成功歌唱比赛的关键步骤：\n" +
                "1. 明确比赛目标和定位（专业/业余/主题等）\n" +
                "2. 制定详细赛制和评分标准\n" +
                "3. 组建专业评委团队并进行培训\n" +
                "4. 设计合理的报名和选拔流程\n" +
                "5. 准备完善的比赛场地和设备\n" +
                "6. 使用本系统进行高效的评分和结果管理\n" +
                "7. 做好宣传推广和后期跟进工作");

        faq.put("如何选择合适的评委", 
                "选择合适评委的建议：\n" +
                "1. 具备专业的音乐知识和演唱经验\n" +
                "2. 公正客观，有良好的职业道德\n" +
                "3. 了解比赛目标受众和风格定位\n" +
                "4. 具备一定的表达能力和点评技巧\n" +
                "5. 结构合理（专业评委、行业专家、大众评委结合）\n" +
                "建议评委数量为奇数，一般3-7人为宜");

        // 数据分析相关问题
        faq.put("如何利用数据分析优化比赛", 
                "利用数据分析优化比赛的方法：\n" +
                "1. 分析历史比赛数据，识别成功模式和改进点\n" +
                "2. 跟踪评分分布，评估比赛竞争性\n" +
                "3. 分析评委评分一致性，识别潜在问题\n" +
                "4. 使用系统的比赛智能分析功能生成详细报告\n" +
                "5. 结合AI建议，持续优化比赛流程和评分标准");

        faq.put("智能评分算法", 
                "本系统的智能评分算法特点：\n" +
                "1. 自动检测和过滤评分中的离群值\n" +
                "2. 采用加权平均方法，中间分数权重更高\n" +
                "3. 支持基于评委历史数据的评分校准\n" +
                "4. 考虑分数分布特征，提供更准确的最终得分\n" +
                "5. 与传统算法相比，能更好地处理主观评分差异");

        // 系统使用相关问题
        faq.put("系统功能", 
                "本系统主要功能包括：\n" +
                "1. 比赛管理：创建、编辑和管理比赛信息\n" +
                "2. 队伍管理：添加、编辑参赛队伍和成员信息\n" +
                "3. 评分管理：评委评分录入和管理\n" +
                "4. 智能分析：算法比较、AI问答、比赛智能分析\n" +
                "5. 历史查询：查看历史比赛和评分记录\n" +
                "6. 数据可视化：提供直观的数据展示和分析\n" +
                "系统支持多角色权限管理（管理员、评委等）");

        faq.put("如何添加新比赛", 
                "添加新比赛的步骤：\n" +
                "1. 登录系统后，点击左侧菜单的\"比赛管理\"\n" +
                "2. 在比赛管理页面，点击\"添加比赛\"按钮\n" +
                "3. 填写比赛名称、日期、地点、规则等信息\n" +
                "4. 保存比赛信息\n" +
                "5. 比赛创建成功后，可以继续添加参赛队伍和评委");

        // 智能匹配算法
        // 先检查是否有直接匹配的常见问题
        for (Map.Entry<String, String> entry : faq.entrySet()) {
            if (question.contains(entry.getKey())) {
                return entry.getValue();
            }
        }
        
        // 关键词匹配 - 增强AI智能性
        if (question.contains("准确性") || question.contains("精确")) {
            return faq.get("如何提高评分准确性");
        } else if (question.contains("分析") || question.contains("结果")) {
            return faq.get("如何分析比赛结果");
        } else if (question.contains("标准") || question.contains("规则")) {
            return faq.get("评分标准");
        } else if (question.contains("差异") || question.contains("不一致")) {
            return faq.get("如何减少评委差异");
        } else if (question.contains("组织") || question.contains("举办")) {
            return faq.get("如何组织一场成功的歌唱比赛");
        } else if (question.contains("评委") || question.contains("评审")) {
            return faq.get("如何选择合适的评委");
        } else if (question.contains("数据") || question.contains("统计")) {
            return faq.get("如何利用数据分析优化比赛");
        } else if (question.contains("智能") || question.contains("算法")) {
            return faq.get("智能评分算法");
        } else if (question.contains("功能") || question.contains("能做什么")) {
            return faq.get("系统功能");
        } else if (question.contains("添加") || question.contains("创建")) {
            return faq.get("如何添加新比赛");
        } else if (question.contains("你好") || question.contains("您好") || question.contains("hi") || question.contains("hello")) {
            return "您好！我是智能问答助手，很高兴为您服务。请问有什么可以帮助您的？";
        } else if (question.contains("谢谢") || question.contains("感谢")) {
            return "不客气！如果您有任何其他问题，请随时提问。";
        }
        
        // 如果没有匹配的问题，返回更智能的通用回答
        return "感谢您的提问。我是智能问答助手，专注于歌唱比赛评分系统的相关问题。\n" +
               "您可以尝试以下常见问题：\n" +
               "- 如何提高评分准确性\n" +
               "- 如何分析比赛结果\n" +
               "- 评分标准\n" +
               "- 如何减少评委差异\n" +
               "- 如何组织一场成功的歌唱比赛\n" +
               "- 系统有哪些功能\n" +
               "或者告诉我您具体想了解什么，我会尽力为您解答。";
    }
    
    /**
     * 调用Qwen-Plus API获取AI回答
     */
    private static String callQwenPlusApi(String question) throws Exception {
        // 配置API参数
        String apiUrl = "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions";
        String apiKey = "sk-49f7aeb1b9bf4f419dc8da983efede57";
        String model = "qwen-plus";

        // 修复JSON格式错误 - 添加缺失的引号
        String requestBody = "{\"model\":\"" + model + "\",\"messages\":[{\"role\":\"user\",\"content\":\"" +
                escapeJson(question) + "\"}],\"temperature\":0.7}";

        // 创建HTTP连接
        URI uri = new URI(apiUrl);
        HttpURLConnection connection = (HttpURLConnection) uri.toURL().openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setRequestProperty("Authorization", "Bearer " + apiKey);
        connection.setConnectTimeout(10000);
        connection.setReadTimeout(10000);
        connection.setDoOutput(true);

        // 发送请求
        try (OutputStream os = connection.getOutputStream()) {
            byte[] input = requestBody.getBytes("utf-8");
            os.write(input, 0, input.length);
        }

        // 获取响应代码和消息
        int responseCode = connection.getResponseCode();
        String responseMessage = connection.getResponseMessage();

        // 读取响应（无论是成功还是错误）
        StringBuilder response = new StringBuilder();
        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(
                        responseCode < 400 ? connection.getInputStream() : connection.getErrorStream(),
                        "utf-8"))) {
            String responseLine;
            while ((responseLine = br.readLine()) != null) {
                response.append(responseLine.trim());
            }
        }

        // 记录完整的响应信息用于调试
        System.out.println("API响应代码: " + responseCode);
        System.out.println("API响应消息: " + responseMessage);
        System.out.println("API响应内容: " + response.toString());

        if (responseCode != 200) {
            throw new RuntimeException("API调用失败: " + responseCode + " - " + responseMessage + " - " + response.toString());
        }

        // 解析JSON响应
        ObjectMapper mapper = new ObjectMapper();
        JsonNode jsonNode = mapper.readTree(response.toString());

        // 增强响应解析
        if (jsonNode.has("choices") && jsonNode.get("choices").isArray()) {
            JsonNode choices = jsonNode.get("choices");
            if (choices.size() > 0) {
                JsonNode firstChoice = choices.get(0);
                if (firstChoice.has("message") && firstChoice.get("message").has("content")) {
                    return firstChoice.get("message").get("content").asText();
                }
            }
        }

        // 备用解析逻辑
        if (jsonNode.has("output") && jsonNode.get("output").has("text")) {
            return jsonNode.get("output").get("text").asText();
        }

        // 如果所有解析尝试都失败，返回原始响应用于调试
        return "无法解析API响应: " + response.toString();
    }
    
    /**
     * 转义JSON字符串中的特殊字符
     */
    private static String escapeJson(String text) {
        if (text == null) return null;
        return text
            .replace("\\", "\\\\")
            .replace("\"", "\\\"")
            .replace("\b", "\\b")
            .replace("\f", "\\f")
            .replace("\n", "\\n")
            .replace("\r", "\\r")
            .replace("\t", "\\t");
    }
}